package com.ken.apollo.controller;

import com.ken.apollo.commons.result.R;
import com.ken.apollo.service.impl.MailBatchSendServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 线程池监控控制器
 *
 * @author Ken
 * @since 2025-08-25
 */
@RestController
@RequestMapping("/api/system/threadpool")
@Slf4j
public class ThreadPoolMonitorController {

    @Autowired
    @Qualifier("mailTaskExecutor")
    private ThreadPoolTaskExecutor mailTaskExecutor;

    @Autowired
    @Qualifier("commonTaskExecutor")
    private ThreadPoolTaskExecutor commonTaskExecutor;

    @Autowired
    private MailBatchSendServiceImpl mailBatchSendService;

    /**
     * 获取所有线程池状态信息
     */
    @GetMapping("/status")
    public R<Map<String, Object>> getThreadPoolStatus() {
        Map<String, Object> result = new HashMap<>();
        
        // 邮件线程池状态
        Map<String, Object> mailPoolStatus = new HashMap<>();
        mailPoolStatus.put("corePoolSize", mailTaskExecutor.getCorePoolSize());
        mailPoolStatus.put("maxPoolSize", mailTaskExecutor.getMaxPoolSize());
        mailPoolStatus.put("activeCount", mailTaskExecutor.getActiveCount());
        mailPoolStatus.put("poolSize", mailTaskExecutor.getPoolSize());
        mailPoolStatus.put("queueSize", mailTaskExecutor.getQueueSize());
        mailPoolStatus.put("queueCapacity", mailTaskExecutor.getQueueCapacity());
        mailPoolStatus.put("completedTaskCount", mailTaskExecutor.getThreadPoolExecutor().getCompletedTaskCount());
        mailPoolStatus.put("taskCount", mailTaskExecutor.getThreadPoolExecutor().getTaskCount());
        mailPoolStatus.put("largestPoolSize", mailTaskExecutor.getThreadPoolExecutor().getLargestPoolSize());
        
        // 通用线程池状态
        Map<String, Object> commonPoolStatus = new HashMap<>();
        commonPoolStatus.put("corePoolSize", commonTaskExecutor.getCorePoolSize());
        commonPoolStatus.put("maxPoolSize", commonTaskExecutor.getMaxPoolSize());
        commonPoolStatus.put("activeCount", commonTaskExecutor.getActiveCount());
        commonPoolStatus.put("poolSize", commonTaskExecutor.getPoolSize());
        commonPoolStatus.put("queueSize", commonTaskExecutor.getQueueSize());
        commonPoolStatus.put("queueCapacity", commonTaskExecutor.getQueueCapacity());
        commonPoolStatus.put("completedTaskCount", commonTaskExecutor.getThreadPoolExecutor().getCompletedTaskCount());
        commonPoolStatus.put("taskCount", commonTaskExecutor.getThreadPoolExecutor().getTaskCount());
        commonPoolStatus.put("largestPoolSize", commonTaskExecutor.getThreadPoolExecutor().getLargestPoolSize());
        
        // 系统信息
        Map<String, Object> systemInfo = new HashMap<>();
        systemInfo.put("availableProcessors", Runtime.getRuntime().availableProcessors());
        systemInfo.put("totalMemory", Runtime.getRuntime().totalMemory());
        systemInfo.put("freeMemory", Runtime.getRuntime().freeMemory());
        systemInfo.put("maxMemory", Runtime.getRuntime().maxMemory());
        
        result.put("mailThreadPool", mailPoolStatus);
        result.put("commonThreadPool", commonPoolStatus);
        result.put("systemInfo", systemInfo);
        result.put("timestamp", System.currentTimeMillis());
        
        log.info("【线程池状态查询】邮件线程池活跃数：{}, 通用线程池活跃数：{}", 
            mailTaskExecutor.getActiveCount(), commonTaskExecutor.getActiveCount());
        
        return R.success(result);
    }

    /**
     * 获取邮件线程池状态
     */
    @GetMapping("/mail")
    public R<String> getMailThreadPoolStatus() {
        String status = mailBatchSendService.getMailThreadPoolStatus();
        return R.success(status);
    }

    /**
     * 获取线程池健康状态
     */
    @GetMapping("/health")
    public R<Map<String, Object>> getThreadPoolHealth() {
        Map<String, Object> health = new HashMap<>();
        
        // 邮件线程池健康状态
        double mailPoolUtilization = (double) mailTaskExecutor.getActiveCount() / mailTaskExecutor.getMaxPoolSize();
        double mailQueueUtilization = (double) mailTaskExecutor.getQueueSize() / mailTaskExecutor.getQueueCapacity();
        
        Map<String, Object> mailHealth = new HashMap<>();
        mailHealth.put("healthy", mailPoolUtilization < 0.8 && mailQueueUtilization < 0.8);
        mailHealth.put("poolUtilization", String.format("%.2f%%", mailPoolUtilization * 100));
        mailHealth.put("queueUtilization", String.format("%.2f%%", mailQueueUtilization * 100));
        mailHealth.put("status", mailPoolUtilization > 0.9 ? "HIGH_LOAD" : 
                               mailPoolUtilization > 0.7 ? "MEDIUM_LOAD" : "NORMAL");
        
        // 通用线程池健康状态
        double commonPoolUtilization = (double) commonTaskExecutor.getActiveCount() / commonTaskExecutor.getMaxPoolSize();
        double commonQueueUtilization = (double) commonTaskExecutor.getQueueSize() / commonTaskExecutor.getQueueCapacity();
        
        Map<String, Object> commonHealth = new HashMap<>();
        commonHealth.put("healthy", commonPoolUtilization < 0.8 && commonQueueUtilization < 0.8);
        commonHealth.put("poolUtilization", String.format("%.2f%%", commonPoolUtilization * 100));
        commonHealth.put("queueUtilization", String.format("%.2f%%", commonQueueUtilization * 100));
        commonHealth.put("status", commonPoolUtilization > 0.9 ? "HIGH_LOAD" : 
                                  commonPoolUtilization > 0.7 ? "MEDIUM_LOAD" : "NORMAL");
        
        health.put("mailThreadPool", mailHealth);
        health.put("commonThreadPool", commonHealth);
        health.put("overallHealthy", ((Map<String, Object>) mailHealth).get("healthy").equals(true) && 
                                   ((Map<String, Object>) commonHealth).get("healthy").equals(true));
        
        return R.success(health);
    }
}